package com.atlassian.extras.core;

import com.atlassian.extras.api.AtlassianLicense;
import com.atlassian.extras.api.LicenseManager;
import com.atlassian.extras.common.LicenseException;
import com.atlassian.extras.decoder.api.LicenseDecoder;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

final class DefaultLicenseManager implements LicenseManager {
	private final Map<String, AtlassianLicense> licenses = new ConcurrentHashMap(
			1);
	private final LicenseDecoder licenseDecoder;
	private final AtlassianLicenseFactory atlassianLicenseFactory;

	DefaultLicenseManager(LicenseDecoder licenseDecoder,
			AtlassianLicenseFactory atlassianLicenseFactory) {
		if (licenseDecoder == null) {
			throw new IllegalArgumentException(
					"licenseDecoder must NOT be null!");
		}
		if (atlassianLicenseFactory == null) {
			throw new IllegalArgumentException(
					"atlassianLicenseFactory must NOT be null!");
		}
		this.atlassianLicenseFactory = atlassianLicenseFactory;
		this.licenseDecoder = licenseDecoder;
	}

	public AtlassianLicense getLicense(String licenseString) {
		if (licenseString == null) {
			throw new IllegalArgumentException("licenseString must NOT be null");
		}

		AtlassianLicense license = (AtlassianLicense) this.licenses
				.get(licenseString);
		if (license == null) {
			license = decodeLicense(licenseString);
			if (license == null) {
				throw new LicenseException("Could not decode license <"
						+ licenseString + ">, "
						+ "decoding returned a null Atlassian license object");
			}

			this.licenses.put(licenseString, license);
		}

		return license;
	}

	private AtlassianLicense decodeLicense(String licenseString) {
		return this.atlassianLicenseFactory.getLicense(this.licenseDecoder
				.decode(licenseString));
	}

	Map<String, AtlassianLicense> getLicenses() {
		return Collections.unmodifiableMap(this.licenses);
	}

	LicenseDecoder getLicenseDecoder() {
		return this.licenseDecoder;
	}

	AtlassianLicenseFactory getAtlassianLicenseFactory() {
		return this.atlassianLicenseFactory;
	}

	public void clear() {
		this.licenses.clear();
	}
}